package zero.tech.games.user.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import zero.tech.core.data.Resp;
import zero.tech.core.util.DatetimeUtil;
import zero.tech.games.common.Code;
import zero.tech.games.common.DiamondChangeType;
import zero.tech.games.common.QueueConsts;
import zero.tech.games.common.TUserAccountUtil;
import zero.tech.games.common.UserLastRoomUtil;
import zero.tech.games.common.data.UserLastRoom;
import zero.tech.games.entity.games.Translog;
import zero.tech.games.entity.log.LogDiamondChange;
import zero.tech.games.entity.user.TUserAccount;
import zero.tech.games.user.data.UpdateDiamondVo;
import zero.tech.games.user.mapper.TUserAccountMapper;
import zero.tech.games.user.mapper.TranslogMapper;
import zero.tech.games.user.service.api.ITradeService;
import zero.tech.redis.lock.RedisLockUtil;
import zero.tech.redis.lock.RedisLockUtil.LockMethod;
import zero.tech.redis.queue.QueueUtil;

@Service
public class TradeServiceImpl implements ITradeService{
	@Autowired
	private RedisLockUtil lockUtil;
	@Autowired
	private UserLastRoomUtil userLastRoomUtil;
	@Autowired
	private TUserAccountMapper userAccountMapper;
	@Autowired
	private TUserAccountUtil userAccountUtil;
	@Autowired
	private QueueUtil queueUtil;
	@Autowired
	private TranslogMapper translogMapper;
	@Override
	public Resp addUserDiamond(int uid, long add_dimond, int diamond_change_type,String diamond_change_desc) {
		Assert.isTrue(add_dimond>0,"交易金币大于0");
		return lockUtil.lockMethod(new LockMethod<Resp>() {
			@Override
			public Resp lockRun() {
				Date now=new Date();
				String day_str=DatetimeUtil.parseDateToString("yyyy-MM-dd", now);
				//邮件增加分,需要检查是否有最后的房间
				UserLastRoom userLastRoom=userLastRoomUtil.getUserLastRoom(String.valueOf(uid));
				if(userLastRoom!=null) {
					return Resp.build(Code.USER_IN_ROOM, "玩家还在房间中,不能操作");
				}
				userAccountMapper.addDiamond(uid,add_dimond);
				//修改缓存
				TUserAccount userAccount=userAccountMapper.getUserAccount(uid);
				userAccountUtil.insertOrUpdate(userAccount);
				//开始记录砖石变化日志
				List<LogDiamondChange> logDiamondChanges = new ArrayList<>();
				LogDiamondChange logDiamondChange = new LogDiamondChange();
				logDiamondChange.setUid(uid);
				long change_num=add_dimond;
				logDiamondChange.setChange_num(change_num);
				logDiamondChange.setChange_type(diamond_change_type);
				logDiamondChange.setChange_desc(diamond_change_desc);
				logDiamondChange.setCur_diamond(userAccount.getDiamond());
				logDiamondChange.setDay_str(day_str);
				logDiamondChange.setCreate_stamp(now);
				logDiamondChanges.add(logDiamondChange);
				queueUtil.putQueueBatch(QueueConsts.QUEUE_LOG_DIAMOND_CHANGE, logDiamondChanges);//推送金币变化日志
				//开始通知账户变化
				userAccountUtil.notifyDiamondChange(uid);
				return Resp.build(Code.OK, "操作成功");
			}
		}, "user_trade_"+uid, 30);
	}
	@Override
	@Transactional
	public Resp gameUpdateDiamondBatch(String order_id, int game_id, String room_id, int room_times, String room_name,
			int total_times, Map<Integer, Long> diamond_change_map) {
		if(diamond_change_map.isEmpty()) {
			return Resp.build(Code.OK, "不用处理");
		}
		return lockUtil.lockMethod(new LockMethod<Resp>() {
			@Override
			public Resp lockRun() {
				Date now=new Date();
				String day_str=DatetimeUtil.parseDateToString("yyyy-MM-dd", now);
				Translog translog=translogMapper.getTranslog(order_id);
				if(translog==null) {
					translog=new Translog(order_id, 0);
					translogMapper.insert(translog);
				}else {
					if(translog.getStatus()==1) {
						//已处理过
						return Resp.build(Code.OK, "已处理过");
					}
				}
				List<UpdateDiamondVo> list = new ArrayList<UpdateDiamondVo>();
				String sql = "";
				for (Entry<Integer, Long> entry : diamond_change_map.entrySet()) {
					Integer uid = entry.getKey();
					Long change = entry.getValue();
					UpdateDiamondVo updateVo = new UpdateDiamondVo(uid, change);
					list.add(updateVo);
					sql += " select * from t_user_account where uid=" + uid + " union all";
				}
				userAccountMapper.updateDiamondBatch(list);
				if(!StringUtils.isBlank(sql)) {
					sql=sql.substring(0, sql.length()-"union all".length());
				}
				List<TUserAccount> userAccounts = userAccountMapper.execute(sql);
				//开始记录日志
				List<LogDiamondChange> logDiamondChanges = new ArrayList<>();
				for(TUserAccount userAccount:userAccounts) {
					int uid=userAccount.getUid();
					long change_num=diamond_change_map.get(uid);
					LogDiamondChange logDiamondChange = new LogDiamondChange();
					logDiamondChange.setUid(uid);
					logDiamondChange.setChange_num(change_num);
					logDiamondChange.setChange_type(DiamondChangeType.GAME_CHANGE);
					logDiamondChange.setChange_desc("游戏变化");
					logDiamondChange.setCur_diamond(userAccount.getDiamond());
					logDiamondChange.setDay_str(day_str);
					logDiamondChange.setCreate_stamp(now);
					logDiamondChanges.add(logDiamondChange);
				}
				translog.setStatus(1);
				translogMapper.update(translog);
				userAccountUtil.insertOrUpdateBatch(userAccounts);
				queueUtil.putQueueBatch(QueueConsts.QUEUE_LOG_DIAMOND_CHANGE, logDiamondChanges);//推送金币变化日志
				return Resp.build(Code.OK, "处理成功");
			}
		}, order_id, 30);
	}

}
